<template>
  <div>
    <div style="display: flex; justify-content: space-between">
      <div style="display: flex; align-items: center; gap: 2px">
        <el-button icon="search" @click="getList" type="success"></el-button>
      </div>
      <el-button type="primary" icon="plus" style="border-radius: 10px" @click="add"
        >添加
      </el-button>
    </div>

    <CommonDialogForm
      v-model:has-loading="loading"
      v-model:visible="dialogAdd"
      v-model:form-params="addDTO"
      :rules="RoleRules.addRules"
      :item-config="RoleParams.formColumn"
      :title="'添加角色表'"
      :width="'20%'"
      :submit-text="'保存'"
      :chancel-text="'取消'"
      :is-submit="true"
      :close-tips="true"
      @submit="onAdd"
    >
    </CommonDialogForm>

    <CommonDialogForm
      v-model:has-loading="loading"
      v-model:visible="dialogUpdate"
      v-model:form-params="updateDTO"
      :rules="RoleRules.updateRules"
      :item-config="RoleParams.formColumn"
      :title="'修改角色表'"
      :width="'20%'"
      :submit-text="'保存'"
      :chancel-text="'取消'"
      :is-submit="true"
      :close-tips="true"
      @submit="onUpdate"
    >
    </CommonDialogForm>

    <CommonPageTable
      :table-column="RoleParams.tableColumn"
      :table-data="searchVO"
      :table-loading="loading"
      :table-attribute="{
        'empty-text': '暂无数据',
        height: TableEnum.height,
      }"
      :page-params="searchDTO.page"
      :page-attribute="{
        size: 'small',
        pageSizes: [10, 20, 50, 100],
        layout: ' total, sizes, prev, pager, next, jumper',
      }"
      @search="getList"
      @update="update"
      @remove="remove"
      @bindMenu="bindMenu"
      @bindUser="bindUser"
    />
    <!--关联用户-->
    <CommonDialog
      title="关联用户"
      v-model:visible="bindUserDialog"
      :width="'25vw'"
      :submit-text="'保存'"
      :chancel-text="'取消'"
      @submit="bindUserSubmit"
      v-model:has-loading="loading"
    >
      <el-transfer
        v-model="bindUserParams.userId"
        :data="userList"
        filterable
        :titles="['用户列表', '已绑定列表']"
      />
    </CommonDialog>
    <!--关联菜单-->
    <CommonDialog
      title="关联菜单"
      v-model:visible="bindMenuDialog"
      :width="'20vw'"
      :submit-text="'保存'"
      :chancel-text="'取消'"
      @submit="bindMenuSubmit"
      v-model:has-loading="loading"
    >
      <el-tree
        ref="treeRef"
        style="max-width: 600px"
        :data="menuTreeList"
        show-checkbox
        node-key="id"
        highlight-current
        :props="defaultProps"
      />
    </CommonDialog>
  </div>
</template>

<script setup lang="ts">
//----------------------------------导入区---------------------------------
import { onMounted, reactive, ref } from 'vue'
import type { ResultPageType } from '@/resources/interface/ResultTypes'
import CommonPageTable from '@/components/CommonPageTable.vue'
import { TableEnum } from '@/enums/TableEnum'
import CommonDialogForm from '@/components/CommonDialogForm.vue'
import CommonDialog from '@/components/CommonDialog.vue'
import ObjectUtils from '@/utils/ObjectUtils'
import { RoleApi } from '@/apis/api/role/RoleApi'
import { RoleParams } from '@/resources/parameters/role/RoleParameters'
import type {
  RoleAddDTOType,
  RoleSearchDTOType,
  RoleSearchVOType,
  RoleUpdateDTOType,
} from '@/resources/interface/role/RoleTypes'
import { RoleRules } from '@/resources/rules/role/RoleRules'
import ElementUtil from '@/utils/ElementUtil'
import type { MenuTreeTypes } from '@/resources/interface/menu/MenuTypes.ts'
import { MenuApi } from '@/apis/api/menu/MenuApi.ts'
import { ElTree } from 'element-plus'
import { RoleMenuParams } from '@/resources/parameters/roleMenu/RoleMenuParameters.ts'
import { RoleMenuApi } from '@/apis/api/roleMenu/RoleMenuApi.ts'
import type { RoleMenuAddDTOType } from '@/resources/interface/roleMenu/RoleMenuTypes.ts'
import type { UserRoleAddDTOType } from '@/resources/interface/userRole/UserRoleTypes.ts'
import { UserRoleParams } from '@/resources/parameters/userRole/UserRoleParameters.ts'
import { UserApi } from '@/apis/api/user/UserApi.ts'
import type { UserSearchVOType } from '@/resources/interface/user/UserTypes.ts'
import { UserRoleApi } from '@/apis/api/userRole/UserRoleApi.ts'

//----------------------------------数据区---------------------------------
const loading = ref(false)
const dialogAdd = ref(false)
const dialogUpdate = ref(false)
const searchDTO = reactive<RoleSearchDTOType>({ ...RoleParams.searchDTO })
const searchVO = ref<ResultPageType>()
let addDTO = reactive<RoleAddDTOType>({ ...RoleParams.addDTO })
let updateDTO = reactive<RoleUpdateDTOType>({ ...RoleParams.updateDTO })
const bindMenuDialog = ref(false)
const bindMenuParams = reactive<RoleMenuAddDTOType>({ ...RoleMenuParams.addDTO })
let menuTreeList = reactive<MenuTreeTypes[]>([])
const defaultProps = {
  children: 'children',
  label: 'name',
}
const treeRef = ref<InstanceType<typeof ElTree>>()
const bindUserDialog = ref(false)
const bindUserParams = reactive<UserRoleAddDTOType>({ ...UserRoleParams.addDTO })
const userList = ref<any[]>([])
// ----------------------------------方法区--------------------------------
/**
 * 关联用户回调
 */
const bindUserSubmit = async () => {
  bindUserDialog.value = false
  await UserRoleApi.add(bindUserParams)
  loading.value = false
}

const bindUser = async (params: RoleSearchVOType) => {
  bindUserDialog.value = true
  loading.value = true
  const result = await UserApi.list()
  userList.value = []
  result.data.forEach((item: UserSearchVOType) => {
    userList.value.push({
      key: item.id,
      label: item.userName,
    })
  })
  const userResult = await UserRoleApi.findRole(params.id)
  bindUserParams.userId = userResult.data
  bindUserParams.roleId = params.id
  loading.value = false
}
/**
 * 添加 角色菜单 回调
 */
const bindMenuSubmit = async () => {
  bindMenuDialog.value = false
  const checkedKeys = treeRef.value!.getCheckedNodes(false, true)
  bindMenuParams.menuId = []
  checkedKeys.forEach((item) => {
    bindMenuParams.menuId.push(item.id)
  })
  await RoleMenuApi.add(bindMenuParams)
  loading.value = false
}

/**
 * 添加 角色菜单 前置
 * @param params
 */
const bindMenu = async (params: RoleSearchVOType) => {
  bindMenuDialog.value = true
  bindMenuParams.roleId = params.id
  loading.value = true
  const result = await MenuApi.getMenuTreeAllApi()
  menuTreeList = result.data

  const roleResult = await MenuApi.findRoleMenuApi(params.id)
  treeRef.value!.setCheckedKeys(roleResult.data)
  loading.value = false
}
/**
 * 添加 角色表 前置
 */
const add = async () => {
  dialogAdd.value = true
}
/**
 * 添加 角色表 回调
 * @param params 表单数据
 */
const onAdd = async (params: RoleAddDTOType) => {
  await RoleApi.add(params)
  loading.value = false
  await getList()
  ObjectUtils.resetObject(addDTO, RoleParams.addDTO)
}
/**
 * 更新 角色表 前置
 * @param vo 选中数据
 */
const update = (vo: RoleSearchVOType) => {
  updateDTO = reactive(ObjectUtils.copy(vo, updateDTO))
  dialogUpdate.value = true
}
/**
 * 更新 角色表 回调
 * @param params 表单数据
 */
const onUpdate = async (params: RoleUpdateDTOType) => {
  await RoleApi.update(params)
  await getList()
}
/**
 * 删除 角色表
 * @param vo 选中数据
 */
const remove = async (vo: RoleSearchVOType) => {
  if (await ElementUtil.openBox({ content: '是否删除,删除后不可恢复！' })) {
    await RoleApi.delete(Array.of(vo.id))
    await getList()
  }
}
/**
 * 获取 角色表 列表
 */
const getList = async () => {
  loading.value = true
  const result = await RoleApi.search(searchDTO)
  searchVO.value = result.data
  loading.value = false
}

onMounted(() => {
  getList()
})
</script>

<style scoped></style>
